//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2021 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto/tree/main/CodeGenerator. DO NOT EDIT.

import Foundation
import SotoCore

extension NetworkFirewall {
    // MARK: Enums

    public enum AttachmentStatus: String, CustomStringConvertible, Codable {
        case creating = "CREATING"
        case deleting = "DELETING"
        case ready = "READY"
        case scaling = "SCALING"
        public var description: String { return self.rawValue }
    }

    public enum ConfigurationSyncState: String, CustomStringConvertible, Codable {
        case inSync = "IN_SYNC"
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    public enum FirewallStatusValue: String, CustomStringConvertible, Codable {
        case deleting = "DELETING"
        case provisioning = "PROVISIONING"
        case ready = "READY"
        public var description: String { return self.rawValue }
    }

    public enum GeneratedRulesType: String, CustomStringConvertible, Codable {
        case allowlist = "ALLOWLIST"
        case denylist = "DENYLIST"
        public var description: String { return self.rawValue }
    }

    public enum LogDestinationType: String, CustomStringConvertible, Codable {
        case cloudwatchlogs = "CloudWatchLogs"
        case kinesisdatafirehose = "KinesisDataFirehose"
        case s3 = "S3"
        public var description: String { return self.rawValue }
    }

    public enum LogType: String, CustomStringConvertible, Codable {
        case alert = "ALERT"
        case flow = "FLOW"
        public var description: String { return self.rawValue }
    }

    public enum PerObjectSyncStatus: String, CustomStringConvertible, Codable {
        case inSync = "IN_SYNC"
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    public enum ResourceStatus: String, CustomStringConvertible, Codable {
        case active = "ACTIVE"
        case deleting = "DELETING"
        public var description: String { return self.rawValue }
    }

    public enum RuleGroupType: String, CustomStringConvertible, Codable {
        case stateful = "STATEFUL"
        case stateless = "STATELESS"
        public var description: String { return self.rawValue }
    }

    public enum StatefulAction: String, CustomStringConvertible, Codable {
        case alert = "ALERT"
        case drop = "DROP"
        case pass = "PASS"
        public var description: String { return self.rawValue }
    }

    public enum StatefulRuleDirection: String, CustomStringConvertible, Codable {
        case any = "ANY"
        case forward = "FORWARD"
        public var description: String { return self.rawValue }
    }

    public enum StatefulRuleProtocol: String, CustomStringConvertible, Codable {
        case dcerpc = "DCERPC"
        case dhcp = "DHCP"
        case dns = "DNS"
        case ftp = "FTP"
        case http = "HTTP"
        case icmp = "ICMP"
        case ikev2 = "IKEV2"
        case imap = "IMAP"
        case ip = "IP"
        case krb5 = "KRB5"
        case msn = "MSN"
        case ntp = "NTP"
        case smb = "SMB"
        case smtp = "SMTP"
        case ssh = "SSH"
        case tcp = "TCP"
        case tftp = "TFTP"
        case tls = "TLS"
        case udp = "UDP"
        public var description: String { return self.rawValue }
    }

    public enum TCPFlag: String, CustomStringConvertible, Codable {
        case ack = "ACK"
        case cwr = "CWR"
        case ece = "ECE"
        case fin = "FIN"
        case psh = "PSH"
        case rst = "RST"
        case syn = "SYN"
        case urg = "URG"
        public var description: String { return self.rawValue }
    }

    public enum TargetType: String, CustomStringConvertible, Codable {
        case httpHost = "HTTP_HOST"
        case tlsSni = "TLS_SNI"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct ActionDefinition: AWSEncodableShape & AWSDecodableShape {
        /// Stateless inspection criteria that publishes the specified metrics to Amazon CloudWatch for the matching packet. This setting defines a CloudWatch dimension value to be published. You can pair this custom action with any of the standard stateless rule actions. For example, you could pair this in a rule action with the standard action that forwards the packet for stateful inspection. Then, when a packet matches the rule, Network Firewall publishes metrics for the packet and forwards it.
        public let publishMetricAction: PublishMetricAction?

        public init(publishMetricAction: PublishMetricAction? = nil) {
            self.publishMetricAction = publishMetricAction
        }

        public func validate(name: String) throws {
            try self.publishMetricAction?.validate(name: "\(name).publishMetricAction")
        }

        private enum CodingKeys: String, CodingKey {
            case publishMetricAction = "PublishMetricAction"
        }
    }

    public struct Address: AWSEncodableShape & AWSDecodableShape {
        /// Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let addressDefinition: String

        public init(addressDefinition: String) {
            self.addressDefinition = addressDefinition
        }

        public func validate(name: String) throws {
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, max: 255)
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, min: 1)
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, pattern: "^([a-fA-F\\d:\\.]+/\\d{1,3})$")
        }

        private enum CodingKeys: String, CodingKey {
            case addressDefinition = "AddressDefinition"
        }
    }

    public struct AssociateFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let firewallPolicyArn: String
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyArn: String, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateFirewallPolicyResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let firewallPolicyArn: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyArn: String? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateSubnetsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The IDs of the subnets that you want to associate with the firewall.
        public let subnetMappings: [SubnetMapping]
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping], updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateSubnetsResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The IDs of the subnets that are associated with the firewall.
        public let subnetMappings: [SubnetMapping]?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping]? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct Attachment: AWSDecodableShape {
        /// The identifier of the firewall endpoint that Network Firewall has instantiated in the subnet. You use this to identify the firewall endpoint in the VPC route tables, when you redirect the VPC traffic through the endpoint.
        public let endpointId: String?
        /// The current status of the firewall endpoint in the subnet. This value reflects both the instantiation of the endpoint in the VPC subnet and the sync states that are reported in the Config settings. When this value is READY, the endpoint is available and configured properly to handle network traffic. When the endpoint isn't available for traffic, this value will reflect its state, for example CREATING, DELETING, or FAILED.
        public let status: AttachmentStatus?
        /// The unique identifier of the subnet that you've specified to be used for a firewall endpoint.
        public let subnetId: String?

        public init(endpointId: String? = nil, status: AttachmentStatus? = nil, subnetId: String? = nil) {
            self.endpointId = endpointId
            self.status = status
            self.subnetId = subnetId
        }

        private enum CodingKeys: String, CodingKey {
            case endpointId = "EndpointId"
            case status = "Status"
            case subnetId = "SubnetId"
        }
    }

    public struct CreateFirewallPolicyRequest: AWSEncodableShape {
        /// A description of the firewall policy.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// The rule groups and policy actions to use in the firewall policy.
        public let firewallPolicy: FirewallPolicy
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let firewallPolicyName: String
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?

        public init(description: String? = nil, dryRun: Bool? = nil, firewallPolicy: FirewallPolicy, firewallPolicyName: String, tags: [Tag]? = nil) {
            self.description = description
            self.dryRun = dryRun
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyName = firewallPolicyName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.firewallPolicy.validate(name: "\(name).firewallPolicy")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case dryRun = "DryRun"
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyName = "FirewallPolicyName"
            case tags = "Tags"
        }
    }

    public struct CreateFirewallPolicyResponse: AWSDecodableShape {
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct CreateFirewallRequest: AWSEncodableShape {
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool?
        /// A description of the firewall.
        public let description: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String
        /// The Amazon Resource Name (ARN) of the FirewallPolicy that you want to use for the firewall.
        public let firewallPolicyArn: String
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// The public subnets to use for your Network Firewall firewalls. Each subnet must belong to a different Availability Zone in the VPC. Network Firewall creates a firewall endpoint in each subnet.
        public let subnetMappings: [SubnetMapping]
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// The unique identifier of the VPC where Network Firewall should create the firewall.  You can't change this setting after you create the firewall.
        public let vpcId: String

        public init(deleteProtection: Bool? = nil, description: String? = nil, firewallName: String, firewallPolicyArn: String, firewallPolicyChangeProtection: Bool? = nil, subnetChangeProtection: Bool? = nil, subnetMappings: [SubnetMapping], tags: [Tag]? = nil, vpcId: String) {
            self.deleteProtection = deleteProtection
            self.description = description
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.subnetChangeProtection = subnetChangeProtection
            self.subnetMappings = subnetMappings
            self.tags = tags
            self.vpcId = vpcId
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws.*")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.vpcId, name: "vpcId", parent: name, max: 128)
            try self.validate(self.vpcId, name: "vpcId", parent: name, min: 1)
            try self.validate(self.vpcId, name: "vpcId", parent: name, pattern: "^vpc-[0-9a-f]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case description = "Description"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case subnetChangeProtection = "SubnetChangeProtection"
            case subnetMappings = "SubnetMappings"
            case tags = "Tags"
            case vpcId = "VpcId"
        }
    }

    public struct CreateFirewallResponse: AWSDecodableShape {
        /// The configuration settings for the firewall. These settings include the firewall policy and the subnets in your VPC to use for the firewall endpoints.
        public let firewall: Firewall?
        /// Detailed information about the current status of a Firewall. You can retrieve this for a firewall by calling DescribeFirewall and providing the firewall name and ARN.
        public let firewallStatus: FirewallStatus?

        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
        }
    }

    public struct CreateRuleGroupRequest: AWSEncodableShape {
        /// The maximum operating resources that this rule group can use. Rule group capacity is fixed at creation. When you update a rule group, you are limited to this capacity. When you reference a rule group from a firewall policy, Network Firewall reserves this capacity for the rule group.  You can retrieve the capacity that would be required for a rule group before you create the rule group by calling CreateRuleGroup with DryRun set to TRUE.   You can't change or exceed this capacity when you update the rule group, so leave room for your rule group to grow.    Capacity for a stateless rule group  For a stateless rule group, the capacity required is the sum of the capacity requirements of the individual rules that you expect to have in the rule group.  To calculate the capacity requirement of a single rule, multiply the capacity requirement values of each of the rule's match settings:   A match setting with no criteria specified has a value of 1.    A match setting with Any specified has a value of 1.    All other match settings have a value equal to the number of elements provided in the setting. For example, a protocol setting ["UDP"] and a source setting ["10.0.0.0/24"] each have a value of 1. A protocol setting ["UDP","TCP"] has a value of 2. A source setting ["10.0.0.0/24","10.0.0.1/24","10.0.0.2/24"] has a value of 3.    A rule with no criteria specified in any of its match settings has a capacity requirement of 1. A rule with protocol setting ["UDP","TCP"], source setting ["10.0.0.0/24","10.0.0.1/24","10.0.0.2/24"], and a single specification or no specification for each of the other match settings has a capacity requirement of 6.   Capacity for a stateful rule group  For a stateful rule group, the minimum capacity required is the number of individual rules that you expect to have in the rule group.
        public let capacity: Int
        /// A description of the rule group.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// An object that defines the rule group rules.   You must provide either this rule group setting or a Rules setting, but not both.
        public let ruleGroup: RuleGroup?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let ruleGroupName: String
        /// The name of a file containing stateful rule group rules specifications in Suricata flat format, with one rule per line. Use this to import your existing Suricata compatible rule groups.   You must provide either this rules setting or a populated RuleGroup setting, but not both.   You can provide your rule group specification in a file through this setting when you create or update your rule group. The call response returns a RuleGroup object that Network Firewall has populated from your file. Network Firewall uses the file contents to populate the rule group rules, but does not maintain a reference to the file or use the file in any way after performing the create or update. If you call DescribeRuleGroup to retrieve the rule group, Network Firewall returns rules settings inside a RuleGroup object.
        public let rules: String?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.
        public let type: RuleGroupType

        public init(capacity: Int, description: String? = nil, dryRun: Bool? = nil, ruleGroup: RuleGroup? = nil, ruleGroupName: String, rules: String? = nil, tags: [Tag]? = nil, type: RuleGroupType) {
            self.capacity = capacity
            self.description = description
            self.dryRun = dryRun
            self.ruleGroup = ruleGroup
            self.ruleGroupName = ruleGroupName
            self.rules = rules
            self.tags = tags
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.ruleGroup?.validate(name: "\(name).ruleGroup")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.rules, name: "rules", parent: name, max: 1_000_000)
            try self.validate(self.rules, name: "rules", parent: name, min: 0)
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case capacity = "Capacity"
            case description = "Description"
            case dryRun = "DryRun"
            case ruleGroup = "RuleGroup"
            case ruleGroupName = "RuleGroupName"
            case rules = "Rules"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct CreateRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct CustomAction: AWSEncodableShape & AWSDecodableShape {
        /// The custom action associated with the action name.
        public let actionDefinition: ActionDefinition
        /// The descriptive name of the custom action. You can't change the name of a custom action after you create it.
        public let actionName: String

        public init(actionDefinition: ActionDefinition, actionName: String) {
            self.actionDefinition = actionDefinition
            self.actionName = actionName
        }

        public func validate(name: String) throws {
            try self.actionDefinition.validate(name: "\(name).actionDefinition")
            try self.validate(self.actionName, name: "actionName", parent: name, max: 128)
            try self.validate(self.actionName, name: "actionName", parent: name, min: 1)
            try self.validate(self.actionName, name: "actionName", parent: name, pattern: "^[a-zA-Z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case actionDefinition = "ActionDefinition"
            case actionName = "ActionName"
        }
    }

    public struct DeleteFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?

        public init(firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil) {
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
        }
    }

    public struct DeleteFirewallPolicyResponse: AWSDecodableShape {
        /// The object containing the definition of the FirewallPolicyResponse that you asked to delete.
        public let firewallPolicyResponse: FirewallPolicyResponse

        public init(firewallPolicyResponse: FirewallPolicyResponse) {
            self.firewallPolicyResponse = firewallPolicyResponse
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
        }
    }

    public struct DeleteFirewallRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DeleteFirewallResponse: AWSDecodableShape {
        public let firewall: Firewall?
        public let firewallStatus: FirewallStatus?

        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
        }
    }

    public struct DeleteResourcePolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group or firewall policy whose resource policy you want to delete.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct DeleteResourcePolicyResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteRuleGroupRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        public init(ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DeleteRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse

        public init(ruleGroupResponse: RuleGroupResponse) {
            self.ruleGroupResponse = ruleGroupResponse
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
        }
    }

    public struct DescribeFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?

        public init(firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil) {
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
        }
    }

    public struct DescribeFirewallPolicyResponse: AWSDecodableShape {
        /// The policy for the specified firewall policy.
        public let firewallPolicy: FirewallPolicy?
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(firewallPolicy: FirewallPolicy? = nil, firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeFirewallRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DescribeFirewallResponse: AWSDecodableShape {
        /// The configuration settings for the firewall. These settings include the firewall policy and the subnets in your VPC to use for the firewall endpoints.
        public let firewall: Firewall?
        /// Detailed information about the current status of a Firewall. You can retrieve this for a firewall by calling DescribeFirewall and providing the firewall name and ARN.
        public let firewallStatus: FirewallStatus?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil, updateToken: String? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeLoggingConfigurationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DescribeLoggingConfigurationResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        public let loggingConfiguration: LoggingConfiguration?

        public init(firewallArn: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.firewallArn = firewallArn
            self.loggingConfiguration = loggingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct DescribeResourcePolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group or firewall policy whose resource policy you want to retrieve.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct DescribeResourcePolicyResponse: AWSDecodableShape {
        /// The AWS Identity and Access Management policy for the resource.
        public let policy: String?

        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct DescribeRuleGroupRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        public init(ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DescribeRuleGroupResponse: AWSDecodableShape {
        /// The object that defines the rules in a rule group. This, along with RuleGroupResponse, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.  AWS Network Firewall uses a rule group to inspect and control network traffic. You define stateless rule groups to inspect individual packets and you define stateful rule groups to inspect packets in the context of their traffic flow.  To use a rule group, you include it by reference in an Network Firewall firewall policy, then you use the policy in a firewall. You can reference a rule group from more than one firewall policy, and you can use a firewall policy in more than one firewall.
        public let ruleGroup: RuleGroup?
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(ruleGroup: RuleGroup? = nil, ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroup = ruleGroup
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroup = "RuleGroup"
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct Dimension: AWSEncodableShape & AWSDecodableShape {
        /// The value to use in the custom metric dimension.
        public let value: String

        public init(value: String) {
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.value, name: "value", parent: name, max: 128)
            try self.validate(self.value, name: "value", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[a-zA-Z0-9-_ ]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case value = "Value"
        }
    }

    public struct DisassociateSubnetsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The unique identifiers for the subnets that you want to disassociate.
        public let subnetIds: [String]
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetIds: [String], updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetIds = subnetIds
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.subnetIds.forEach {
                try validate($0, name: "subnetIds[]", parent: name, max: 128)
                try validate($0, name: "subnetIds[]", parent: name, min: 1)
                try validate($0, name: "subnetIds[]", parent: name, pattern: "^subnet-[0-9a-f]+$")
            }
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetIds = "SubnetIds"
            case updateToken = "UpdateToken"
        }
    }

    public struct DisassociateSubnetsResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The IDs of the subnets that are associated with the firewall.
        public let subnetMappings: [SubnetMapping]?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping]? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct Firewall: AWSDecodableShape {
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool?
        /// A description of the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The unique identifier for the firewall.
        public let firewallId: String
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy. The relationship of firewall to firewall policy is many to one. Each firewall requires one firewall policy association, and you can use the same firewall policy for multiple firewalls.
        public let firewallPolicyArn: String
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// The public subnets that Network Firewall is using for the firewall. Each subnet must belong to a different Availability Zone.
        public let subnetMappings: [SubnetMapping]
        public let tags: [Tag]?
        /// The unique identifier of the VPC where the firewall is in use.
        public let vpcId: String

        public init(deleteProtection: Bool? = nil, description: String? = nil, firewallArn: String? = nil, firewallId: String, firewallName: String? = nil, firewallPolicyArn: String, firewallPolicyChangeProtection: Bool? = nil, subnetChangeProtection: Bool? = nil, subnetMappings: [SubnetMapping], tags: [Tag]? = nil, vpcId: String) {
            self.deleteProtection = deleteProtection
            self.description = description
            self.firewallArn = firewallArn
            self.firewallId = firewallId
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.subnetChangeProtection = subnetChangeProtection
            self.subnetMappings = subnetMappings
            self.tags = tags
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallId = "FirewallId"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case subnetChangeProtection = "SubnetChangeProtection"
            case subnetMappings = "SubnetMappings"
            case tags = "Tags"
            case vpcId = "VpcId"
        }
    }

    public struct FirewallMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct FirewallPolicy: AWSEncodableShape & AWSDecodableShape {
        /// References to the stateless rule groups that are used in the policy. These define the inspection criteria in stateful rules.
        public let statefulRuleGroupReferences: [StatefulRuleGroupReference]?
        /// The custom action definitions that are available for use in the firewall policy's StatelessDefaultActions setting. You name each custom action that you define, and then you can use it by name in your default actions specifications.
        public let statelessCustomActions: [CustomAction]?
        /// The actions to take on a packet if it doesn't match any of the stateless rules in the policy. If you want non-matching packets to be forwarded for stateful inspection, specify aws:forward_to_sfe.  You must specify one of the standard actions: aws:pass, aws:drop, or aws:forward_to_sfe. In addition, you can specify custom actions that are compatible with your standard section choice. For example, you could specify ["aws:pass"] or you could specify ["aws:pass", “customActionName”]. For information about compatibility, see the custom action descriptions under CustomAction.
        public let statelessDefaultActions: [String]
        /// The actions to take on a fragmented packet if it doesn't match any of the stateless rules in the policy. If you want non-matching fragmented packets to be forwarded for stateful inspection, specify aws:forward_to_sfe.  You must specify one of the standard actions: aws:pass, aws:drop, or aws:forward_to_sfe. In addition, you can specify custom actions that are compatible with your standard section choice. For example, you could specify ["aws:pass"] or you could specify ["aws:pass", “customActionName”]. For information about compatibility, see the custom action descriptions under CustomAction.
        public let statelessFragmentDefaultActions: [String]
        /// References to the stateless rule groups that are used in the policy. These define the matching criteria in stateless rules.
        public let statelessRuleGroupReferences: [StatelessRuleGroupReference]?

        public init(statefulRuleGroupReferences: [StatefulRuleGroupReference]? = nil, statelessCustomActions: [CustomAction]? = nil, statelessDefaultActions: [String], statelessFragmentDefaultActions: [String], statelessRuleGroupReferences: [StatelessRuleGroupReference]? = nil) {
            self.statefulRuleGroupReferences = statefulRuleGroupReferences
            self.statelessCustomActions = statelessCustomActions
            self.statelessDefaultActions = statelessDefaultActions
            self.statelessFragmentDefaultActions = statelessFragmentDefaultActions
            self.statelessRuleGroupReferences = statelessRuleGroupReferences
        }

        public func validate(name: String) throws {
            try self.statefulRuleGroupReferences?.forEach {
                try $0.validate(name: "\(name).statefulRuleGroupReferences[]")
            }
            try self.statelessCustomActions?.forEach {
                try $0.validate(name: "\(name).statelessCustomActions[]")
            }
            try self.statelessRuleGroupReferences?.forEach {
                try $0.validate(name: "\(name).statelessRuleGroupReferences[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case statefulRuleGroupReferences = "StatefulRuleGroupReferences"
            case statelessCustomActions = "StatelessCustomActions"
            case statelessDefaultActions = "StatelessDefaultActions"
            case statelessFragmentDefaultActions = "StatelessFragmentDefaultActions"
            case statelessRuleGroupReferences = "StatelessRuleGroupReferences"
        }
    }

    public struct FirewallPolicyMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let arn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let name: String?

        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct FirewallPolicyResponse: AWSDecodableShape {
        /// A description of the firewall policy.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.  If this response is for a create request that had DryRun set to TRUE, then this ARN is a placeholder that isn't attached to a valid resource.
        public let firewallPolicyArn: String
        /// The unique identifier for the firewall policy.
        public let firewallPolicyId: String
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let firewallPolicyName: String
        /// The current status of the firewall policy. You can retrieve this for a firewall policy by calling DescribeFirewallPolicy and providing the firewall policy's name or ARN.
        public let firewallPolicyStatus: ResourceStatus?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?

        public init(description: String? = nil, firewallPolicyArn: String, firewallPolicyId: String, firewallPolicyName: String, firewallPolicyStatus: ResourceStatus? = nil, tags: [Tag]? = nil) {
            self.description = description
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyId = firewallPolicyId
            self.firewallPolicyName = firewallPolicyName
            self.firewallPolicyStatus = firewallPolicyStatus
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyId = "FirewallPolicyId"
            case firewallPolicyName = "FirewallPolicyName"
            case firewallPolicyStatus = "FirewallPolicyStatus"
            case tags = "Tags"
        }
    }

    public struct FirewallStatus: AWSDecodableShape {
        /// The configuration sync state for the firewall. This summarizes the sync states reported in the Config settings for all of the Availability Zones where you have configured the firewall.  When you create a firewall or update its configuration, for example by adding a rule group to its firewall policy, Network Firewall distributes the configuration changes to all zones where the firewall is in use. This summary indicates whether the configuration changes have been applied everywhere.  This status must be IN_SYNC for the firewall to be ready for use, but it doesn't indicate that the firewall is ready. The Status setting indicates firewall readiness.
        public let configurationSyncStateSummary: ConfigurationSyncState
        /// The readiness of the configured firewall to handle network traffic across all of the Availability Zones where you've configured it. This setting is READY only when the ConfigurationSyncStateSummary value is IN_SYNC and the Attachment Status values for all of the configured subnets are READY.
        public let status: FirewallStatusValue
        /// The subnets that you've configured for use by the Network Firewall firewall. This contains one array element per Availability Zone where you've configured a subnet. These objects provide details of the information that is summarized in the ConfigurationSyncStateSummary and Status, broken down by zone and configuration object.
        public let syncStates: [String: SyncState]?

        public init(configurationSyncStateSummary: ConfigurationSyncState, status: FirewallStatusValue, syncStates: [String: SyncState]? = nil) {
            self.configurationSyncStateSummary = configurationSyncStateSummary
            self.status = status
            self.syncStates = syncStates
        }

        private enum CodingKeys: String, CodingKey {
            case configurationSyncStateSummary = "ConfigurationSyncStateSummary"
            case status = "Status"
            case syncStates = "SyncStates"
        }
    }

    public struct Header: AWSEncodableShape & AWSDecodableShape {
        /// The destination IP address or address range to inspect for, in CIDR notation. To match with any address, specify ANY.  Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let destination: String
        /// The destination port to inspect for. You can specify an individual port, for example 1994 and you can specify a port range, for example 1990-1994. To match with any port, specify ANY.
        public let destinationPort: String
        /// The direction of traffic flow to inspect. If set to ANY, the inspection matches bidirectional traffic, both from the source to the destination and from the destination to the source. If set to FORWARD, the inspection only matches traffic going from the source to the destination.
        public let direction: StatefulRuleDirection
        /// The protocol to inspect for. To match with any protocol, specify ANY.
        public let `protocol`: StatefulRuleProtocol
        /// The source IP address or address range to inspect for, in CIDR notation. To match with any address, specify ANY.  Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let source: String
        /// The source port to inspect for. You can specify an individual port, for example 1994 and you can specify a port range, for example 1990-1994. To match with any port, specify ANY.
        public let sourcePort: String

        public init(destination: String, destinationPort: String, direction: StatefulRuleDirection, protocol: StatefulRuleProtocol, source: String, sourcePort: String) {
            self.destination = destination
            self.destinationPort = destinationPort
            self.direction = direction
            self.`protocol` = `protocol`
            self.source = source
            self.sourcePort = sourcePort
        }

        public func validate(name: String) throws {
            try self.validate(self.destination, name: "destination", parent: name, max: 1024)
            try self.validate(self.destination, name: "destination", parent: name, min: 1)
            try self.validate(self.destination, name: "destination", parent: name, pattern: "^.*$")
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, max: 1024)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, min: 1)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, pattern: "^.*$")
            try self.validate(self.source, name: "source", parent: name, max: 1024)
            try self.validate(self.source, name: "source", parent: name, min: 1)
            try self.validate(self.source, name: "source", parent: name, pattern: "^.*$")
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, max: 1024)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, min: 1)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, pattern: "^.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case destination = "Destination"
            case destinationPort = "DestinationPort"
            case direction = "Direction"
            case `protocol` = "Protocol"
            case source = "Source"
            case sourcePort = "SourcePort"
        }
    }

    public struct IPSet: AWSEncodableShape & AWSDecodableShape {
        /// The list of IP addresses and address ranges, in CIDR notation.
        public let definition: [String]

        public init(definition: [String]) {
            self.definition = definition
        }

        public func validate(name: String) throws {
            try self.definition.forEach {
                try validate($0, name: "definition[]", parent: name, min: 1)
                try validate($0, name: "definition[]", parent: name, pattern: "^.*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case definition = "Definition"
        }
    }

    public struct ListFirewallPoliciesRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListFirewallPoliciesResponse: AWSDecodableShape {
        /// The metadata for the firewall policies. Depending on your setting for max results and the number of firewall policies that you have, this might not be the full list.
        public let firewallPolicies: [FirewallPolicyMetadata]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        public init(firewallPolicies: [FirewallPolicyMetadata]? = nil, nextToken: String? = nil) {
            self.firewallPolicies = firewallPolicies
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicies = "FirewallPolicies"
            case nextToken = "NextToken"
        }
    }

    public struct ListFirewallsRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The unique identifiers of the VPCs that you want Network Firewall to retrieve the firewalls for. Leave this blank to retrieve all firewalls that you have defined.
        public let vpcIds: [String]?

        public init(maxResults: Int? = nil, nextToken: String? = nil, vpcIds: [String]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.vpcIds = vpcIds
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "[0-9A-Za-z:\\/+=]+$")
            try self.vpcIds?.forEach {
                try validate($0, name: "vpcIds[]", parent: name, max: 128)
                try validate($0, name: "vpcIds[]", parent: name, min: 1)
                try validate($0, name: "vpcIds[]", parent: name, pattern: "^vpc-[0-9a-f]+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case vpcIds = "VpcIds"
        }
    }

    public struct ListFirewallsResponse: AWSDecodableShape {
        /// The firewall metadata objects for the VPCs that you specified. Depending on your setting for max results and the number of firewalls you have, a single call might not be the full list.
        public let firewalls: [FirewallMetadata]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        public init(firewalls: [FirewallMetadata]? = nil, nextToken: String? = nil) {
            self.firewalls = firewalls
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewalls = "Firewalls"
            case nextToken = "NextToken"
        }
    }

    public struct ListRuleGroupsRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListRuleGroupsResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The rule group metadata objects that you've defined. Depending on your setting for max results and the number of rule groups, this might not be the full list.
        public let ruleGroups: [RuleGroupMetadata]?

        public init(nextToken: String? = nil, ruleGroups: [RuleGroupMetadata]? = nil) {
            self.nextToken = nextToken
            self.ruleGroups = ruleGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case ruleGroups = "RuleGroups"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String

        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceArn: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "[0-9A-Za-z:\\/+=]+$")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The tags that are associated with the resource.
        public let tags: [Tag]?

        public init(nextToken: String? = nil, tags: [Tag]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct LogDestinationConfig: AWSEncodableShape & AWSDecodableShape {
        /// The named location for the logs, provided in a key:value mapping that is specific to the chosen destination type.    For an Amazon S3 bucket, provide the name of the bucket, with key bucketName, and optionally provide a prefix, with key prefix. The following example specifies an Amazon S3 bucket named DOC-EXAMPLE-BUCKET and the prefix alerts:   "LogDestination": { "bucketName": "DOC-EXAMPLE-BUCKET", "prefix": "alerts" }    For a CloudWatch log group, provide the name of the CloudWatch log group, with key logGroup. The following example specifies a log group named alert-log-group:   "LogDestination": { "logGroup": "alert-log-group" }    For a Kinesis Data Firehose delivery stream, provide the name of the delivery stream, with key deliveryStream. The following example specifies a delivery stream named alert-delivery-stream:   "LogDestination": { "deliveryStream": "alert-delivery-stream" }
        public let logDestination: [String: String]
        /// The type of storage destination to send these logs to. You can send logs to an Amazon S3 bucket, a CloudWatch log group, or a Kinesis Data Firehose delivery stream.
        public let logDestinationType: LogDestinationType
        /// The type of log to send. Alert logs report traffic that matches a StatefulRule with an action setting that sends an alert log message. Flow logs are standard network traffic flow logs.
        public let logType: LogType

        public init(logDestination: [String: String], logDestinationType: LogDestinationType, logType: LogType) {
            self.logDestination = logDestination
            self.logDestinationType = logDestinationType
            self.logType = logType
        }

        public func validate(name: String) throws {
            try self.logDestination.forEach {
                try validate($0.key, name: "logDestination.key", parent: name, max: 50)
                try validate($0.key, name: "logDestination.key", parent: name, min: 3)
                try validate($0.key, name: "logDestination.key", parent: name, pattern: "^[0-9A-Za-z.\\-_@\\/]+$")
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, max: 1024)
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, pattern: "[\\s\\S]*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case logDestination = "LogDestination"
            case logDestinationType = "LogDestinationType"
            case logType = "LogType"
        }
    }

    public struct LoggingConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Defines the logging destinations for the logs for a firewall. Network Firewall generates logs for stateful rule groups.
        public let logDestinationConfigs: [LogDestinationConfig]

        public init(logDestinationConfigs: [LogDestinationConfig]) {
            self.logDestinationConfigs = logDestinationConfigs
        }

        public func validate(name: String) throws {
            try self.logDestinationConfigs.forEach {
                try $0.validate(name: "\(name).logDestinationConfigs[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case logDestinationConfigs = "LogDestinationConfigs"
        }
    }

    public struct MatchAttributes: AWSEncodableShape & AWSDecodableShape {
        /// The destination ports to inspect for. If not specified, this matches with any destination port. This setting is only used for protocols 6 (TCP) and 17 (UDP).  You can specify individual ports, for example 1994 and you can specify port ranges, for example 1990-1994.
        public let destinationPorts: [PortRange]?
        /// The destination IP addresses and address ranges to inspect for, in CIDR notation. If not specified, this matches with any destination address.
        public let destinations: [Address]?
        /// The protocols to inspect for, specified using each protocol's assigned internet protocol number (IANA). If not specified, this matches with any protocol.
        public let protocols: [Int]?
        /// The source ports to inspect for. If not specified, this matches with any source port. This setting is only used for protocols 6 (TCP) and 17 (UDP).  You can specify individual ports, for example 1994 and you can specify port ranges, for example 1990-1994.
        public let sourcePorts: [PortRange]?
        /// The source IP addresses and address ranges to inspect for, in CIDR notation. If not specified, this matches with any source address.
        public let sources: [Address]?
        /// The TCP flags and masks to inspect for. If not specified, this matches with any settings. This setting is only used for protocol 6 (TCP).
        public let tCPFlags: [TCPFlagField]?

        public init(destinationPorts: [PortRange]? = nil, destinations: [Address]? = nil, protocols: [Int]? = nil, sourcePorts: [PortRange]? = nil, sources: [Address]? = nil, tCPFlags: [TCPFlagField]? = nil) {
            self.destinationPorts = destinationPorts
            self.destinations = destinations
            self.protocols = protocols
            self.sourcePorts = sourcePorts
            self.sources = sources
            self.tCPFlags = tCPFlags
        }

        public func validate(name: String) throws {
            try self.destinationPorts?.forEach {
                try $0.validate(name: "\(name).destinationPorts[]")
            }
            try self.destinations?.forEach {
                try $0.validate(name: "\(name).destinations[]")
            }
            try self.protocols?.forEach {
                try validate($0, name: "protocols[]", parent: name, max: 255)
                try validate($0, name: "protocols[]", parent: name, min: 0)
            }
            try self.sourcePorts?.forEach {
                try $0.validate(name: "\(name).sourcePorts[]")
            }
            try self.sources?.forEach {
                try $0.validate(name: "\(name).sources[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case destinationPorts = "DestinationPorts"
            case destinations = "Destinations"
            case protocols = "Protocols"
            case sourcePorts = "SourcePorts"
            case sources = "Sources"
            case tCPFlags = "TCPFlags"
        }
    }

    public struct PerObjectStatus: AWSDecodableShape {
        public let syncStatus: PerObjectSyncStatus?

        public init(syncStatus: PerObjectSyncStatus? = nil) {
            self.syncStatus = syncStatus
        }

        private enum CodingKeys: String, CodingKey {
            case syncStatus = "SyncStatus"
        }
    }

    public struct PortRange: AWSEncodableShape & AWSDecodableShape {
        /// The lower limit of the port range. This must be less than or equal to the ToPort specification.
        public let fromPort: Int
        /// The upper limit of the port range. This must be greater than or equal to the FromPort specification.
        public let toPort: Int

        public init(fromPort: Int, toPort: Int) {
            self.fromPort = fromPort
            self.toPort = toPort
        }

        public func validate(name: String) throws {
            try self.validate(self.fromPort, name: "fromPort", parent: name, max: 65535)
            try self.validate(self.fromPort, name: "fromPort", parent: name, min: 0)
            try self.validate(self.toPort, name: "toPort", parent: name, max: 65535)
            try self.validate(self.toPort, name: "toPort", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case fromPort = "FromPort"
            case toPort = "ToPort"
        }
    }

    public struct PortSet: AWSEncodableShape & AWSDecodableShape {
        /// The set of port ranges.
        public let definition: [String]?

        public init(definition: [String]? = nil) {
            self.definition = definition
        }

        public func validate(name: String) throws {
            try self.definition?.forEach {
                try validate($0, name: "definition[]", parent: name, min: 1)
                try validate($0, name: "definition[]", parent: name, pattern: "^.*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case definition = "Definition"
        }
    }

    public struct PublishMetricAction: AWSEncodableShape & AWSDecodableShape {
        public let dimensions: [Dimension]

        public init(dimensions: [Dimension]) {
            self.dimensions = dimensions
        }

        public func validate(name: String) throws {
            try self.dimensions.forEach {
                try $0.validate(name: "\(name).dimensions[]")
            }
            try self.validate(self.dimensions, name: "dimensions", parent: name, max: 1)
            try self.validate(self.dimensions, name: "dimensions", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case dimensions = "Dimensions"
        }
    }

    public struct PutResourcePolicyRequest: AWSEncodableShape {
        /// The AWS Identity and Access Management policy statement that lists the accounts that you want to share your rule group or firewall policy with and the operations that you want the accounts to be able to perform.  For a rule group resource, you can specify the following operations in the Actions section of the statement:   network-firewall:CreateFirewallPolicy   network-firewall:UpdateFirewallPolicy   network-firewall:ListRuleGroups   For a firewall policy resource, you can specify the following operations in the Actions section of the statement:   network-firewall:CreateFirewall   network-firewall:UpdateFirewall   network-firewall:AssociateFirewallPolicy   network-firewall:ListFirewallPolicies   In the Resource section of the statement, you specify the ARNs for the rule groups and firewall policies that you want to share with the account that you specified in Arn.
        public let policy: String
        /// The Amazon Resource Name (ARN) of the account that you want to share rule groups and firewall policies with.
        public let resourceArn: String

        public init(policy: String, resourceArn: String) {
            self.policy = policy
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.policy, name: "policy", parent: name, max: 395_000)
            try self.validate(self.policy, name: "policy", parent: name, min: 1)
            try self.validate(self.policy, name: "policy", parent: name, pattern: ".*\\S.*")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
            case resourceArn = "ResourceArn"
        }
    }

    public struct PutResourcePolicyResponse: AWSDecodableShape {
        public init() {}
    }

    public struct RuleDefinition: AWSEncodableShape & AWSDecodableShape {
        /// The actions to take on a packet that matches one of the stateless rule definition's match attributes. You must specify a standard action and you can add custom actions.   Network Firewall only forwards a packet for stateful rule inspection if you specify aws:forward_to_sfe for a rule that the packet matches, or if the packet doesn't match any stateless rule and you specify aws:forward_to_sfe for the StatelessDefaultActions setting for the FirewallPolicy.  For every rule, you must specify exactly one of the following standard actions.     aws:pass - Discontinues all inspection of the packet and permits it to go to its intended destination.    aws:drop - Discontinues all inspection of the packet and blocks it from going to its intended destination.    aws:forward_to_sfe - Discontinues stateless inspection of the packet and forwards it to the stateful rule engine for inspection.    Additionally, you can specify a custom action. To do this, you define a custom action by name and type, then provide the name you've assigned to the action in this Actions setting. For information about the options, see CustomAction.  To provide more than one action in this setting, separate the settings with a comma. For example, if you have a custom PublishMetrics action that you've named MyMetricsAction, then you could specify the standard action aws:pass and the custom action with [“aws:pass”, “MyMetricsAction”].
        public let actions: [String]
        /// Criteria for Network Firewall to use to inspect an individual packet in stateless rule inspection. Each match attributes set can include one or more items such as IP address, CIDR range, port number, protocol, and TCP flags.
        public let matchAttributes: MatchAttributes

        public init(actions: [String], matchAttributes: MatchAttributes) {
            self.actions = actions
            self.matchAttributes = matchAttributes
        }

        public func validate(name: String) throws {
            try self.matchAttributes.validate(name: "\(name).matchAttributes")
        }

        private enum CodingKeys: String, CodingKey {
            case actions = "Actions"
            case matchAttributes = "MatchAttributes"
        }
    }

    public struct RuleGroup: AWSEncodableShape & AWSDecodableShape {
        /// The stateful rules or stateless rules for the rule group.
        public let rulesSource: RulesSource
        /// Settings that are available for use in the rules in the rule group. You can only use these for stateful rule groups.
        public let ruleVariables: RuleVariables?

        public init(rulesSource: RulesSource, ruleVariables: RuleVariables? = nil) {
            self.rulesSource = rulesSource
            self.ruleVariables = ruleVariables
        }

        public func validate(name: String) throws {
            try self.rulesSource.validate(name: "\(name).rulesSource")
            try self.ruleVariables?.validate(name: "\(name).ruleVariables")
        }

        private enum CodingKeys: String, CodingKey {
            case rulesSource = "RulesSource"
            case ruleVariables = "RuleVariables"
        }
    }

    public struct RuleGroupMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the rule group.
        public let arn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let name: String?

        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct RuleGroupResponse: AWSDecodableShape {
        /// The maximum operating resources that this rule group can use. Rule group capacity is fixed at creation. When you update a rule group, you are limited to this capacity. When you reference a rule group from a firewall policy, Network Firewall reserves this capacity for the rule group.  You can retrieve the capacity that would be required for a rule group before you create the rule group by calling CreateRuleGroup with DryRun set to TRUE.
        public let capacity: Int?
        /// A description of the rule group.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the rule group.  If this response is for a create request that had DryRun set to TRUE, then this ARN is a placeholder that isn't attached to a valid resource.
        public let ruleGroupArn: String
        /// The unique identifier for the rule group.
        public let ruleGroupId: String
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let ruleGroupName: String
        /// Detailed information about the current status of a rule group.
        public let ruleGroupStatus: ResourceStatus?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.
        public let type: RuleGroupType?

        public init(capacity: Int? = nil, description: String? = nil, ruleGroupArn: String, ruleGroupId: String, ruleGroupName: String, ruleGroupStatus: ResourceStatus? = nil, tags: [Tag]? = nil, type: RuleGroupType? = nil) {
            self.capacity = capacity
            self.description = description
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupId = ruleGroupId
            self.ruleGroupName = ruleGroupName
            self.ruleGroupStatus = ruleGroupStatus
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case capacity = "Capacity"
            case description = "Description"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupId = "RuleGroupId"
            case ruleGroupName = "RuleGroupName"
            case ruleGroupStatus = "RuleGroupStatus"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct RuleOption: AWSEncodableShape & AWSDecodableShape {
        public let keyword: String
        public let settings: [String]?

        public init(keyword: String, settings: [String]? = nil) {
            self.keyword = keyword
            self.settings = settings
        }

        public func validate(name: String) throws {
            try self.validate(self.keyword, name: "keyword", parent: name, max: 128)
            try self.validate(self.keyword, name: "keyword", parent: name, min: 1)
            try self.validate(self.keyword, name: "keyword", parent: name, pattern: ".*")
            try self.settings?.forEach {
                try validate($0, name: "settings[]", parent: name, max: 8192)
                try validate($0, name: "settings[]", parent: name, min: 1)
                try validate($0, name: "settings[]", parent: name, pattern: ".*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case keyword = "Keyword"
            case settings = "Settings"
        }
    }

    public struct RuleVariables: AWSEncodableShape & AWSDecodableShape {
        /// A list of IP addresses and address ranges, in CIDR notation.
        public let iPSets: [String: IPSet]?
        /// A list of port ranges.
        public let portSets: [String: PortSet]?

        public init(iPSets: [String: IPSet]? = nil, portSets: [String: PortSet]? = nil) {
            self.iPSets = iPSets
            self.portSets = portSets
        }

        public func validate(name: String) throws {
            try self.iPSets?.forEach {
                try validate($0.key, name: "iPSets.key", parent: name, max: 32)
                try validate($0.key, name: "iPSets.key", parent: name, min: 1)
                try validate($0.key, name: "iPSets.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).iPSets[\"\($0.key)\"]")
            }
            try self.portSets?.forEach {
                try validate($0.key, name: "portSets.key", parent: name, max: 32)
                try validate($0.key, name: "portSets.key", parent: name, min: 1)
                try validate($0.key, name: "portSets.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).portSets[\"\($0.key)\"]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case iPSets = "IPSets"
            case portSets = "PortSets"
        }
    }

    public struct RulesSource: AWSEncodableShape & AWSDecodableShape {
        /// Stateful inspection criteria for a domain list rule group.
        public let rulesSourceList: RulesSourceList?
        /// Stateful inspection criteria, provided in Suricata compatible intrusion prevention system (IPS) rules. Suricata is an open-source network IPS that includes a standard rule-based language for network traffic inspection. These rules contain the inspection criteria and the action to take for traffic that matches the criteria, so this type of rule group doesn't have a separate action setting. You can provide the rules from a file that you've stored in an Amazon S3 bucket, or by providing the rules in a Suricata rules string. To import from Amazon S3, provide the fully qualified name of the file that contains the rules definitions. To provide a Suricata rule string, provide the complete, Suricata compatible rule.
        public let rulesString: String?
        /// The 5-tuple stateful inspection criteria. This contains an array of individual 5-tuple stateful rules to be used together in a stateful rule group.
        public let statefulRules: [StatefulRule]?
        /// Stateless inspection criteria to be used in a stateless rule group.
        public let statelessRulesAndCustomActions: StatelessRulesAndCustomActions?

        public init(rulesSourceList: RulesSourceList? = nil, rulesString: String? = nil, statefulRules: [StatefulRule]? = nil, statelessRulesAndCustomActions: StatelessRulesAndCustomActions? = nil) {
            self.rulesSourceList = rulesSourceList
            self.rulesString = rulesString
            self.statefulRules = statefulRules
            self.statelessRulesAndCustomActions = statelessRulesAndCustomActions
        }

        public func validate(name: String) throws {
            try self.validate(self.rulesString, name: "rulesString", parent: name, max: 1_000_000)
            try self.validate(self.rulesString, name: "rulesString", parent: name, min: 0)
            try self.statefulRules?.forEach {
                try $0.validate(name: "\(name).statefulRules[]")
            }
            try self.statelessRulesAndCustomActions?.validate(name: "\(name).statelessRulesAndCustomActions")
        }

        private enum CodingKeys: String, CodingKey {
            case rulesSourceList = "RulesSourceList"
            case rulesString = "RulesString"
            case statefulRules = "StatefulRules"
            case statelessRulesAndCustomActions = "StatelessRulesAndCustomActions"
        }
    }

    public struct RulesSourceList: AWSEncodableShape & AWSDecodableShape {
        /// Whether you want to allow or deny access to the domains in your target list.
        public let generatedRulesType: GeneratedRulesType
        /// The domains that you want to inspect for in your traffic flows. To provide multiple domains, separate them with commas.
        public let targets: [String]
        public let targetTypes: [TargetType]

        public init(generatedRulesType: GeneratedRulesType, targets: [String], targetTypes: [TargetType]) {
            self.generatedRulesType = generatedRulesType
            self.targets = targets
            self.targetTypes = targetTypes
        }

        private enum CodingKeys: String, CodingKey {
            case generatedRulesType = "GeneratedRulesType"
            case targets = "Targets"
            case targetTypes = "TargetTypes"
        }
    }

    public struct StatefulRule: AWSEncodableShape & AWSDecodableShape {
        /// Defines what Network Firewall should do with the packets in a traffic flow when the flow matches the stateful rule criteria. For all actions, Network Firewall performs the specified action and discontinues stateful inspection of the traffic flow.  The actions for a stateful rule are defined as follows:     PASS - Permits the packets to go to the intended destination.    DROP - Blocks the packets from going to the intended destination and sends an alert log message, if alert logging is configured in the Firewall LoggingConfiguration.     ALERT - Permits the packets to go to the intended destination and sends an alert log message, if alert logging is configured in the Firewall LoggingConfiguration.  You can use this action to test a rule that you intend to use to drop traffic. You can enable the rule with ALERT action, verify in the logs that the rule is filtering as you want, then change the action to DROP.
        public let action: StatefulAction
        /// The stateful 5-tuple inspection criteria for this rule, used to inspect traffic flows.
        public let header: Header
        public let ruleOptions: [RuleOption]

        public init(action: StatefulAction, header: Header, ruleOptions: [RuleOption]) {
            self.action = action
            self.header = header
            self.ruleOptions = ruleOptions
        }

        public func validate(name: String) throws {
            try self.header.validate(name: "\(name).header")
            try self.ruleOptions.forEach {
                try $0.validate(name: "\(name).ruleOptions[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case action = "Action"
            case header = "Header"
            case ruleOptions = "RuleOptions"
        }
    }

    public struct StatefulRuleGroupReference: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the stateful rule group.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct StatelessRule: AWSEncodableShape & AWSDecodableShape {
        /// A setting that indicates the order in which to run this rule relative to all of the rules that are defined for a stateless rule group. Network Firewall evaluates the rules in a rule group starting with the lowest priority setting. You must ensure that the priority settings are unique for the rule group.  Each stateless rule group uses exactly one StatelessRulesAndCustomActions object, and each StatelessRulesAndCustomActions contains exactly one StatelessRules object. To ensure unique priority settings for your rule groups, set unique priorities for the stateless rules that you define inside any single StatelessRules object. You can change the priority settings of your rules at any time. To make it easier to insert rules later, number them so there's a wide range in between, for example use 100, 200, and so on.
        public let priority: Int
        /// Defines the stateless 5-tuple packet inspection criteria and the action to take on a packet that matches the criteria.
        public let ruleDefinition: RuleDefinition

        public init(priority: Int, ruleDefinition: RuleDefinition) {
            self.priority = priority
            self.ruleDefinition = ruleDefinition
        }

        public func validate(name: String) throws {
            try self.validate(self.priority, name: "priority", parent: name, max: 65535)
            try self.validate(self.priority, name: "priority", parent: name, min: 1)
            try self.ruleDefinition.validate(name: "\(name).ruleDefinition")
        }

        private enum CodingKeys: String, CodingKey {
            case priority = "Priority"
            case ruleDefinition = "RuleDefinition"
        }
    }

    public struct StatelessRuleGroupReference: AWSEncodableShape & AWSDecodableShape {
        /// An integer setting that indicates the order in which to run the stateless rule groups in a single FirewallPolicy. Network Firewall applies each stateless rule group to a packet starting with the group that has the lowest priority setting. You must ensure that the priority settings are unique within each policy.
        public let priority: Int
        /// The Amazon Resource Name (ARN) of the stateless rule group.
        public let resourceArn: String

        public init(priority: Int, resourceArn: String) {
            self.priority = priority
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.priority, name: "priority", parent: name, max: 65535)
            try self.validate(self.priority, name: "priority", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
        }

        private enum CodingKeys: String, CodingKey {
            case priority = "Priority"
            case resourceArn = "ResourceArn"
        }
    }

    public struct StatelessRulesAndCustomActions: AWSEncodableShape & AWSDecodableShape {
        /// Defines an array of individual custom action definitions that are available for use by the stateless rules in this StatelessRulesAndCustomActions specification. You name each custom action that you define, and then you can use it by name in your StatelessRule RuleDefinition Actions specification.
        public let customActions: [CustomAction]?
        /// Defines the set of stateless rules for use in a stateless rule group.
        public let statelessRules: [StatelessRule]

        public init(customActions: [CustomAction]? = nil, statelessRules: [StatelessRule]) {
            self.customActions = customActions
            self.statelessRules = statelessRules
        }

        public func validate(name: String) throws {
            try self.customActions?.forEach {
                try $0.validate(name: "\(name).customActions[]")
            }
            try self.statelessRules.forEach {
                try $0.validate(name: "\(name).statelessRules[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case customActions = "CustomActions"
            case statelessRules = "StatelessRules"
        }
    }

    public struct SubnetMapping: AWSEncodableShape & AWSDecodableShape {
        /// The unique identifier for the subnet.
        public let subnetId: String

        public init(subnetId: String) {
            self.subnetId = subnetId
        }

        private enum CodingKeys: String, CodingKey {
            case subnetId = "SubnetId"
        }
    }

    public struct SyncState: AWSDecodableShape {
        /// The attachment status of the firewall's association with a single VPC subnet. For each configured subnet, Network Firewall creates the attachment by instantiating the firewall endpoint in the subnet so that it's ready to take traffic. This is part of the FirewallStatus.
        public let attachment: Attachment?
        /// The configuration status of the firewall endpoint in a single VPC subnet. Network Firewall provides each endpoint with the rules that are configured in the firewall policy. Each time you add a subnet or modify the associated firewall policy, Network Firewall synchronizes the rules in the endpoint, so it can properly filter network traffic. This is part of the FirewallStatus.
        public let config: [String: PerObjectStatus]?

        public init(attachment: Attachment? = nil, config: [String: PerObjectStatus]? = nil) {
            self.attachment = attachment
            self.config = config
        }

        private enum CodingKeys: String, CodingKey {
            case attachment = "Attachment"
            case config = "Config"
        }
    }

    public struct TCPFlagField: AWSEncodableShape & AWSDecodableShape {
        /// Used in conjunction with the Masks setting to define the flags that must be set and flags that must not be set in order for the packet to match. This setting can only specify values that are also specified in the Masks setting. For the flags that are specified in the masks setting, the following must be true for the packet to match:    The ones that are set in this flags setting must be set in the packet.    The ones that are not set in this flags setting must also not be set in the packet.
        public let flags: [TCPFlag]
        /// The set of flags to consider in the inspection. To inspect all flags in the valid values list, leave this with no setting.
        public let masks: [TCPFlag]?

        public init(flags: [TCPFlag], masks: [TCPFlag]? = nil) {
            self.flags = flags
            self.masks = masks
        }

        private enum CodingKeys: String, CodingKey {
            case flags = "Flags"
            case masks = "Masks"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The part of the key:value pair that defines a tag. You can use a tag key to describe a category of information, such as "customer." Tag keys are case-sensitive.
        public let key: String
        /// The part of the key:value pair that defines a tag. You can use a tag value to describe a specific value within a category, such as "companyA" or "companyB." Tag values are case-sensitive.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^.*$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 0)
            try self.validate(self.value, name: "value", parent: name, pattern: "^.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        public let tags: [Tag]

        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws.*")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^.*$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateFirewallDeleteProtectionRequest: AWSEncodableShape {
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(deleteProtection: Bool, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.deleteProtection = deleteProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDeleteProtectionResponse: AWSDecodableShape {
        public let deleteProtection: Bool?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(deleteProtection: Bool? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.deleteProtection = deleteProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDescriptionRequest: AWSEncodableShape {
        /// The new description for the firewall. If you omit this setting, Network Firewall removes the description for the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(description: String? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.description = description
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDescriptionResponse: AWSDecodableShape {
        /// A description of the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(description: String? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.description = description
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyChangeProtectionRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyChangeProtection: Bool, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyChangeProtectionResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyChangeProtection: Bool? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyRequest: AWSEncodableShape {
        /// A description of the firewall policy.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// The updated firewall policy to use for the firewall.
        public let firewallPolicy: FirewallPolicy
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(description: String? = nil, dryRun: Bool? = nil, firewallPolicy: FirewallPolicy, firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil, updateToken: String) {
            self.description = description
            self.dryRun = dryRun
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.firewallPolicy.validate(name: "\(name).firewallPolicy")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case dryRun = "DryRun"
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyResponse: AWSDecodableShape {
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateLoggingConfigurationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// Defines how Network Firewall performs logging for a firewall. If you omit this setting, Network Firewall disables logging for the firewall.
        public let loggingConfiguration: LoggingConfiguration?

        public init(firewallArn: String? = nil, firewallName: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.loggingConfiguration = loggingConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.loggingConfiguration?.validate(name: "\(name).loggingConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct UpdateLoggingConfigurationResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        public let loggingConfiguration: LoggingConfiguration?

        public init(firewallArn: String? = nil, firewallName: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.loggingConfiguration = loggingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct UpdateRuleGroupRequest: AWSEncodableShape {
        /// A description of the rule group.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// An object that defines the rule group rules.   You must provide either this rule group setting or a Rules setting, but not both.
        public let ruleGroup: RuleGroup?
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// The name of a file containing stateful rule group rules specifications in Suricata flat format, with one rule per line. Use this to import your existing Suricata compatible rule groups.   You must provide either this rules setting or a populated RuleGroup setting, but not both.   You can provide your rule group specification in a file through this setting when you create or update your rule group. The call response returns a RuleGroup object that Network Firewall has populated from your file. Network Firewall uses the file contents to populate the rule group rules, but does not maintain a reference to the file or use the file in any way after performing the create or update. If you call DescribeRuleGroup to retrieve the rule group, Network Firewall returns rules settings inside a RuleGroup object.
        public let rules: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(description: String? = nil, dryRun: Bool? = nil, ruleGroup: RuleGroup? = nil, ruleGroupArn: String? = nil, ruleGroupName: String? = nil, rules: String? = nil, type: RuleGroupType? = nil, updateToken: String) {
            self.description = description
            self.dryRun = dryRun
            self.ruleGroup = ruleGroup
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.rules = rules
            self.type = type
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.ruleGroup?.validate(name: "\(name).ruleGroup")
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.rules, name: "rules", parent: name, max: 1_000_000)
            try self.validate(self.rules, name: "rules", parent: name, min: 0)
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case dryRun = "DryRun"
            case ruleGroup = "RuleGroup"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case rules = "Rules"
            case type = "Type"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        public init(ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateSubnetChangeProtectionRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetChangeProtection: Bool, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetChangeProtection = subnetChangeProtection
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws.*")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetChangeProtection = "SubnetChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateSubnetChangeProtectionResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetChangeProtection: Bool? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetChangeProtection = subnetChangeProtection
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetChangeProtection = "SubnetChangeProtection"
            case updateToken = "UpdateToken"
        }
    }
}
